using System;
using System.Text;
using System.IO;
// ReSharper disable RedundantUsingDirective
using System.Collections;
// ReSharper restore RedundantUsingDirective
using System.Collections.Generic;

namespace Netkk.Library
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class VCard
    {
        public VCard()
        {
            BirthDate = DateTime.MinValue;
            Addresses = new List<DeliveryAddress>();
            PhoneNumbers = new List<TelephoneNumber>();
            EmailAddresses = new List<String>();
        }

        #region Public Properties

        public string FormattedName { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string NamePrefix { get; set; }
        public string NameSuffix { get; set; }
        public DateTime BirthDate { get; set; }
        public List<DeliveryAddress> Addresses { get; set; }
        public List<TelephoneNumber> PhoneNumbers { get; set; }
        public List<String> EmailAddresses { get; set; }
        public string Internet { get; set; }
        public string Title { get; set; }
        public string Role { get; set; }
        public string Organization { get; set; }

        #endregion

        #region Public Methods

        public void Generate(string filePath, FileMode mode)
        {
            using (FileStream fs = new FileStream(filePath, mode))
            {
                Generate(fs);
            }
        }

        public void Generate(Stream outputStream)
        {
            using (StreamWriter sw = new StreamWriter(outputStream, Encoding.Default))
            {
                sw.Write(ToString());
            }
        }

        #endregion

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            //Start VCard
            sb.Append("BEGIN:VCARD\r\nVERSION:2.1\r\n");

            //Add Formatted name
            if (FormattedName != null)
                sb.Append("FN:" + FormattedName + "\r\n");

            //Add the name
            sb.Append("N:" + LastName + ";");
            sb.Append(FirstName + ";");
            sb.Append(MiddleName + ";");
            sb.Append(NamePrefix + ";");
            sb.Append(NameSuffix + "\r\n");

            //Add a birthday
            if (BirthDate != DateTime.MinValue)
                sb.Append("BDAY:" + BirthDate.ToString("yyyyMMdd") + "\r\n");

            //Add Delivery Addresses
            foreach (DeliveryAddress da in Addresses)
                sb.Append(da.ToString());

            //Add phone numbers
            foreach (TelephoneNumber phone in PhoneNumbers)
                sb.Append(phone.ToString());

            //Add email address
            foreach (string email in EmailAddresses)
                sb.Append("EMAIL; INTERNET:" + email + "\r\n");

            sb.Append("URL;HOME:" + Internet + "\r\n");

            //Add Title
            sb.Append("TITLE:" + Title + "\r\n");

            //Business Category
            sb.Append("ROLE:" + Role + "\r\n");

            //Organization
            sb.Append("ORG:" + Organization + "\r\n");

            sb.Append("END:VCARD\r\n");

            return sb.ToString();
        }
    }

    public class DeliveryAddress
    {

        public DeliveryAddress()
        {

        }
        public DeliveryAddress(AddressType DeliveryAddressType)
        {
            this.DeliveryAddressType = DeliveryAddressType;
        }

        public string PostOfficeAddress { get; set; }
        public string ExtendedAddress { get; set; }
        public string Street { get; set; }
        public string Locality { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public AddressType DeliveryAddressType { get; set; }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("ADR;" + Enum.GetName(typeof(AddressType), DeliveryAddressType) + ":");
            sb.Append(PostOfficeAddress + ";");
            sb.Append(ExtendedAddress + ";");
            sb.Append(Street + ";");
            sb.Append(Locality + ";");
            sb.Append(Region + ";");
            sb.Append(PostalCode + ";");
            sb.Append(Country + "\r\n");

            return sb.ToString();
        }

    }

    public enum AddressType
    {
        DOM,
        INTL,
        POSTAL,
        PARCEL,
        HOME,
        WORK
    }

    public class TelephoneNumber
    {
        public TelephoneNumber()
        {
        }
        public TelephoneNumber(TelephoneNumberType PhoneNumberType)
        {
            this.PhoneNumberType = PhoneNumberType;
        }
        public TelephoneNumber(TelephoneNumberType PhoneNumberType, string PhoneNumber)
        {
            this.PhoneNumberType = PhoneNumberType;
            this.PhoneNumber = PhoneNumber;
        }

        public string PhoneNumber { get; set; }
        public TelephoneNumberType PhoneNumberType { get; set; }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("TEL;" + Enum.GetName(typeof(TelephoneNumberType), PhoneNumberType) + ":");
            sb.Append(PhoneNumber + "\r\n");

            return sb.ToString();
        }
    }

    public enum TelephoneNumberType
    {
        PREF,
        WORK,
        HOME,
        VOICE,
        FAX,
        MSG,
        CELL,
        PAGER,
        BBS,
        MODEM,
        CAR
    }
}